package com.simple.auth.service.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.TypeReference;
import com.simple.auth.domain.dto.RefreshTokenDto;
import com.simple.auth.domain.vo.AuthSuccessVO;
import com.simple.auth.enums.AuthType;
import com.simple.auth.event.AuthSuccessEvent;
import com.simple.common.constant.CommonConstants;
import com.simple.framework.core.domain.BaseUser;
import com.simple.framework.core.domain.LoginUser;
import com.simple.framework.core.redis.RedisService;
import com.simple.framework.utils.JwtUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * @Description 认证服务工具类
 * @Author xiaoke
 * @Date 2024/8/10 18:00
 * @Version 1.0
 */
@Service
public class AuthServiceCommon {

    private final RedisService redisService;

    private final ApplicationEventPublisher eventPublisher;


    @Autowired
    public AuthServiceCommon(RedisService redisService, ApplicationEventPublisher eventPublisher) {
        this.redisService = redisService;
        this.eventPublisher = eventPublisher;
    }

    /**
     * 构建认证成功VO
     *
     * @param user      用户信息
     * @param userPerms 权限列表
     * @param authType  认证类型
     * @return AuthSuccessVO
     */
    public AuthSuccessVO buildAuthSuccessVO(BaseUser user, List<String> userPerms, AuthType authType) {
        AuthSuccessVO authSuccessVO = new AuthSuccessVO();
        user.setPassword(null);
        LoginUser loginUser = new LoginUser(user, userPerms);
        authSuccessVO.setUser(user);
        authSuccessVO.setPermissions(userPerms);
        // 设置过期时间
        LocalDateTime now = LocalDateTime.now();
        authSuccessVO.setExpires(now.plusSeconds(JwtUtil.JWT_TTL / 1000));
        authSuccessVO.setAccessToken(JwtUtil.createJWT(user.getId().toString()));

        // 生成refreshToken
        String RefreshUUID = UUID.randomUUID().toString();
        String refreshTokenKey = CommonConstants.AUTH_REFRESH_TOKEN + user.getUsername();
        // 如果是app认证
        if(authType == AuthType.APP) {
            refreshTokenKey = CommonConstants.AUTH_APP_REFRESH_TOKEN + user.getUsername();
        }
        String userKey = CommonConstants.AUTH_USER + user.getId();

        HashMap<String, String> RefreshMap = new HashMap<>();
        RefreshMap.put("username", user.getUsername());
        RefreshMap.put("uuId", RefreshUUID);
        authSuccessVO.setRefreshToken(JwtUtil.createJWT(JSON.toJSONString(RefreshMap), JwtUtil.JWT_TTL * 20));
        // 删除之前的refreshToken
        redisService.deleteObject(refreshTokenKey);
        // 删除之前的用户信息
        redisService.deleteObject(userKey);
        // 缓存refreshToken
        redisService.setCacheObject(refreshTokenKey, RefreshUUID, 100L, TimeUnit.HOURS);
        // 缓存用户信息
        redisService.setCacheObject(userKey, loginUser, 5L, TimeUnit.HOURS);
        // 发布登录成功事件
        eventPublisher.publishEvent(new AuthSuccessEvent(this, user, authType));
        return authSuccessVO;
    }

    public Map<String, String> getRefreshMap(RefreshTokenDto dto) {
        String refreshToken = dto.getRefreshToken();
        if(refreshToken == null){
            return null;
        }
        Map<String, String> map;
        try {
            map = JSON.parseObject(
                    JwtUtil.parseJWT(refreshToken).getSubject(),
                    new TypeReference<HashMap<String, String>>() {
                    }
            );
        } catch (Exception e) {
            return null;
        }
        return map;
    }


}
